package zlog

import (
	"context"
	"strconv"
	"strings"
	"sync"
	"time"
)

// DefConfig 默认配置
var DefConfig = Config{Dir: "../log", Way: configWayConsole}

var writers = new(sync.Map)
var logLock = new(sync.RWMutex)

// Init 初始化配置
func Init(config Config) {
	if len(config.Dir) != 0 {
		DefConfig.Dir = config.Dir
	}

	if config.Way == configWayLocal || config.Way == configWayRemote || config.Way == configWayConsole {
		DefConfig.Way = config.Way
	}
}

func New(ctx context.Context) Factory {
	switch DefConfig.Way {
	case configWayLocal:
		return newLocalLogger(ctx)
	case configWayRemote:
		return newRemoteLogger(ctx)
	case configWayConsole:
		return newConsoleLogger(ctx)
	default:
		return newConsoleLogger(ctx)
	}
}

func NewSystem(ctx context.Context) Factory {
	return newLocalLogger(ctx).SetFile("system")
}

func NewAppError(ctx context.Context) Factory {
	return newLocalLogger(ctx).SetFile("error")
}

// sn 生成sn
func sn() string {
	return strconv.FormatInt(time.Now().UnixNano(), 10)
}

func (l Logger) format(level, msg string, fields ...Field) string {
	t := time.Now().Format("2006-01-02 15:04:05.000000")

	// 时间
	b := strings.Builder{}
	b.WriteString(t)
	b.WriteString(splicing)

	// sn
	b.WriteString(l.sn)
	b.WriteString(splicing)

	// level
	b.WriteString(level)
	b.WriteString(splicing)

	// 消息标记
	b.WriteString(msg)

	if l.prefix != "" {
		// prefix
		b.WriteString(splicing)
		b.WriteString(l.prefix)
	}

	for _, field := range fields {
		bf := strings.Builder{}
		bf.WriteString(field.Key)
		bf.WriteString(separator)
		bf.WriteString(field.Val)

		b.WriteString(splicing)
		b.WriteString(bf.String())
	}

	if l.suffix != "" {
		// suffix
		b.WriteString(splicing)
		b.WriteString(l.suffix)
	}
	b.WriteString(wrap)
	return b.String()
}
